package com.life.notes.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.life.notes.config.exception.SystemException;
import com.life.notes.config.interceptor.BaseContextHandler;
import com.life.notes.config.utils.TreeBuilderUtil;
import com.life.notes.dao.SysRoleMenuMapper;
import com.life.notes.dao.SysUserMapper;
import com.life.notes.dao.SysUserRoleMapper;
import com.life.notes.dto.UserQueryPara;
import com.life.notes.model.SysMenuEntity;
import com.life.notes.model.SysRoleEntity;
import com.life.notes.model.SysUserEntity;
import com.life.notes.service.SysUserService;
import com.life.notes.vo.ButtonVO;
import com.life.notes.vo.MenuVO;
import com.life.notes.vo.UserInfoVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * @Description 系统用户业务实现
 * @Author Sans
 * @CreateTime 2019/9/14 15:57
 */
@Service("sysUserService")
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUserEntity> implements SysUserService {

    @Autowired
    SysUserRoleMapper userRoleMapper;
    @Autowired
    SysRoleMenuMapper roleMenuMapper;

    /**
     * 根据用户名查询实体
     * @Author Sans
     * @CreateTime 2019/9/14 16:30
     * @Param  username 用户名
     * @Return SysUserEntity 用户实体
     */
    @Override
    public SysUserEntity selectUserByName(String username) {
        QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SysUserEntity::getUsername,username);
        return this.baseMapper.selectOne(queryWrapper);
    }
    /**
     * 通过用户ID查询角色集合
     * @Author Sans
     * @CreateTime 2019/9/18 18:01
     * @Param  userId 用户ID
     * @Return List<SysRoleEntity> 角色名集合
     */
    @Override
    public List<SysRoleEntity> selectSysRoleByUserId(Integer userId) {
        return this.baseMapper.selectSysRoleByUserId(userId);
    }

    /**
     * 根据用户ID查询权限集合
     * @Author Sans
     * @CreateTime 2019/9/18 18:01
     * @Param userId 用户ID
     * @Return List<SysMenuEntity> 角色名集合
     */
    @Override
    public List<SysMenuEntity> selectSysMenuByUserId(Integer userId) {
        return this.baseMapper.selectSysMenuByUserId(userId);
    }

    @Override
    public IPage<SysUserEntity> listPage(UserQueryPara filter) {
        Page<SysUserEntity> page = new Page<>(filter.getPage(), filter.getLimit());
        return this.baseMapper.selectUsers(page, filter);
    }

    @Override
    public List<SysUserEntity> list(UserQueryPara filter) {
        return this.baseMapper.selectUsers(filter);
    }

    @Override
    public UserInfoVO getCurrentUserInfo() {
        SysUserEntity user = this.baseMapper.selectById(BaseContextHandler.getUserId());
        UserInfoVO userInfoVO = new UserInfoVO();
        BeanUtil.copyProperties( user,userInfoVO);

        Set<String> roles = new HashSet();
        Set<MenuVO> menuVOS = new HashSet();
        Set<ButtonVO> buttonVOS = new HashSet();

        //查询某个用户的角色
        List<SysRoleEntity> roleList = userRoleMapper.selectRoleByUserId( user.getId() );
        if(roleList != null && !roleList.isEmpty() ){
            roles.add( roleList.get(0).getCode() );

            //查询某个角色的菜单
            List<SysMenuEntity> menuList = roleMenuMapper.selectMenusByRoleId( roleList.get(0).getId() );
            if(menuList != null && !menuList.isEmpty() ){
                menuList.stream().filter(Objects::nonNull).forEach(menu -> {
                    if ("button".equals(menu.getType().toLowerCase())) {
                        //如果权限是按钮，就添加到按钮里面
                        ButtonVO buttonVO = new ButtonVO();
                        BeanUtil.copyProperties(menu, buttonVO);
                        buttonVOS.add(buttonVO);
                    }
                    if ("menu".equals(menu.getType().toLowerCase())) {
                        //如果权限是菜单，就添加到菜单里面
                        MenuVO menuVO = new MenuVO();
                        BeanUtil.copyProperties(menu, menuVO);
                        menuVOS.add(menuVO);
                    }
                });
            }
        }
        userInfoVO.getRoles().addAll( roles );
        userInfoVO.getButtons().addAll( buttonVOS );
        userInfoVO.getMenus().addAll( TreeBuilderUtil.buildTree(menuVOS) );
        return userInfoVO;
    }

    @Override
    public Integer saveUser(SysUserEntity para) {
        if (para.getId()!=null) {
            SysUserEntity user = this.baseMapper.selectById(para.getId());
            para.setPassword(new BCryptPasswordEncoder().encode(para.getPwd()));
            this.baseMapper.updateById(para);
        } else {
            para.setPassword(new BCryptPasswordEncoder().encode(para.getPwd()));
            this.baseMapper.insert(para);
        }
        return para.getId();
    }

    @Override
    public Integer updatePersonalInfo(SysUserEntity para) {
        if (para.getId()==null){
            throw new SystemException("用户信息异常丢失，请重新登录尝试修改个人信息！");
        }
        if ( StringUtils.isBlank( para.getUsername() ) ){
            throw new SystemException("账号不能为空！");
        }
        if ( StringUtils.isBlank( para.getNickName() ) ){
            throw new SystemException("昵称不能为空！");
        }
        SysUserEntity user = this.baseMapper.selectById( para.getId() );
        if ( StringUtils.isNotBlank( para.getPwd() ) ){
            if (para.getPwd().trim().length() < 6){
                throw new SystemException("请设置至少6位数密码！");
            }
            // 更新密码
            para.setPassword(new BCryptPasswordEncoder().encode(para.getPwd()));
        } else {
            para.setPwd(null);
        }

        // 验证账号是否重复
        UserQueryPara userQueryPara = new UserQueryPara();
        userQueryPara.setAccount( para.getUsername() );
        List<SysUserEntity> userList = this.baseMapper.selectUsers(userQueryPara);
        if ( !CollectionUtils.isEmpty( userList ) ){
            if ( !para.getUsername().equals( user.getUsername() ) || userList.size() > 1 ){
                throw new SystemException( "账号重复，请重新输入！" );
            }
        }
        this.baseMapper.updateById(para);
        return para.getId();
    }
}